#pragma once
#include <vector>
#include "Utils.h"
#include <memory>

template<typename T>
struct Node
{
    Node(T value)
        : data(new T(value))
    {
    }
    Node* next;
    T* data;
};

template<typename T>
class LockFreeStack
{
public:
    LockFreeStack()
        : m_nodeHead(NULL)
    {

    }
    ~LockFreeStack()
    {

    }

    void Push(const T& data);
    T* Pop();

private:
    Node<T>* m_nodeHead;
};


template<typename T>
void LockFreeStack<T>::Push(const T& data)
{
    Node<T>* newNode = new Node<T>(data);
    do 
    {
        newNode->next = m_nodeHead;
    }
    while(!CompareAndExchange<Node<T>*>(&m_nodeHead, newNode->next, newNode));
}

template<typename T>
/*std::auto_ptr<T>*/T* LockFreeStack<T>::Pop()
{
    Node<T>* oldHead = NULL;
    do
    {
        oldHead = m_nodeHead;
        if (oldHead == NULL)
        {
            return NULL;
        }
        Sleep(1);
    }
    while(!CompareAndExchange<Node<T>*>(&m_nodeHead, oldHead, oldHead->next));

    T* result = oldHead ? oldHead->data : NULL;
    delete oldHead;
    return result/*std::auto_ptr<T>(0)*/;
}